/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package view.system;

import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;
import main.ServicesList;
import model.system.Policy;
import model.system.SystemGroupAccess;
import model.system.SystemGroupAccessId;
import model.system.SystemMenu;
import org.apache.log4j.Logger;
import utility.Constants;
import utility.NameValueList;
import utility.com.CheckboxTableRenderer;
import utility.com.HeaderCheckBoxHandler;
import utility.typeSafe.StatusCheckBox;

/**
 *
 * @author Yusup Jauhari Shandi <in.visi>
 */
public class GroupAccessFrm extends javax.swing.JFrame {

     private SystemMenuTM tableModel;
     private List<SystemGroupAccess> groupAccess;
    private List<SystemMenu> items;
    private static Logger log = Logger.getLogger(GroupAccessFrm.class);
    
    final JCheckBox checkAdd = new JCheckBox();
    final JCheckBox checkEdit = new JCheckBox();
    final JCheckBox checkDelete = new JCheckBox();
    final JCheckBox checkPrint = new JCheckBox();
    final JCheckBox checkApprove = new JCheckBox();
    private final int COL_NO = 0;
    private final int COL_MODUL = 1;
    private final int COL_MENU = 2;
    private final int COL_ADD = 3;
    private final int COL_EDIT = 4;
    private final int COL_DELETE = 5;
    private final int COL_PRINT = 6;
    private final int COL_APPROVE = 7;
    private final int COL_ID = 8;
    
    /**
     * Creates new form GroupAccessFrm
         */
    public GroupAccessFrm() {
        initComponents();
    }

    public void execute(boolean withVisible) {
        initGrid();  
        initForm();
        initComponentsRules();
        if (withVisible)
            setVisible(true);
    } 
    
    private void initGrid() {
         tableModel = new SystemMenuTM();
       
         grid.setModel(tableModel);
         TableCellRenderer renderer = new HeaderRenderer(grid.getTableHeader(), COL_ADD,Constants.POLICY_ADD);
         grid.getColumnModel().getColumn(COL_ADD).setHeaderRenderer(renderer);
         renderer = new HeaderRenderer(grid.getTableHeader(), COL_EDIT,Constants.POLICY_EDIT);
         grid.getColumnModel().getColumn(COL_EDIT).setHeaderRenderer(renderer);
         renderer = new HeaderRenderer(grid.getTableHeader(), COL_PRINT,Constants.POLICY_PRINT);
         grid.getColumnModel().getColumn(COL_PRINT).setHeaderRenderer(renderer);
         renderer = new HeaderRenderer(grid.getTableHeader(), COL_DELETE,Constants.POLICY_DELETE);
         grid.getColumnModel().getColumn(COL_DELETE).setHeaderRenderer(renderer);
         renderer = new HeaderRenderer(grid.getTableHeader(), COL_APPROVE,Constants.POLICY_APPROVAL);
         grid.getColumnModel().getColumn(COL_APPROVE).setHeaderRenderer(renderer);
          
       //   tableModel.addTableModelListener(new HeaderCheckBoxHandler(grid, COL_ADD));
        checkAdd.setEnabled(true);
        checkEdit.setEnabled(true);
        checkDelete.setEnabled(true);
        checkPrint.setEnabled(true);
        checkApprove.setEnabled(true);        
        grid.getColumnModel().getColumn(COL_ADD).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_EDIT).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_DELETE).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_PRINT).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_APPROVE).setCellRenderer(new CheckboxTableRenderer());
        grid.getColumnModel().getColumn(COL_ADD).setCellEditor(new DefaultCellEditor(checkAdd));
        grid.getColumnModel().getColumn(COL_EDIT).setCellEditor(new DefaultCellEditor(checkEdit));
        grid.getColumnModel().getColumn(COL_DELETE).setCellEditor(new DefaultCellEditor(checkDelete));
        grid.getColumnModel().getColumn(COL_PRINT).setCellEditor(new DefaultCellEditor(checkPrint));
        grid.getColumnModel().getColumn(COL_APPROVE).setCellEditor(new DefaultCellEditor(checkApprove));
         grid.getColumnModel().getColumn(COL_ID).setMaxWidth(0);
    }
    
    private void initForm() {
        cmbGroup.setModel(ServicesList.getSystemGroupService().getCombo(null, null,false));
        cmbModul.setModel(ServicesList.getSystemMenuService().getModules(null, null,true));
    }
    
    private void initComponentsRules() {
      checkAdd.addActionListener(new GridActionListener());
      checkEdit.addActionListener(new GridActionListener());
      checkDelete.addActionListener(new GridActionListener());
      checkPrint.addActionListener(new GridActionListener());
      checkApprove.addActionListener(new GridActionListener());
    }
    
    private void loadData(){
        tableModel.clear();
        int grpId = Integer.parseInt(((NameValueList) cmbGroup.getSelectedItem()).getKey());
     
        
        items = ServicesList.getSystemMenuService().getSystemMenu();
        int i=0;
        for (SystemMenu menu : items){
            //String groupPolicy = "";
          //  SystemGroupAccess grp = ServicesList.getSystemGroupAccessService().getAccessByMenuAndGroupId(menu.getMenuId(), grpId);
            //if (grp!=null) groupPolicy = grp.getPolicy();
            Policy policy = ServicesList.getSystemGroupAccessService().allowAccess(menu.getMenuId(), grpId);
            //Boolean tmp =  groupPolicy.indexOf("ADD")>-1;
            //if(tmp==null) tmp = Boolean.FALSE;
            items.get(i).getAllowAction().setCanAdd(policy.isCanAdd());
            
//            tmp = groupPolicy.indexOf("EDIT")>-1;
//            if(tmp==null) tmp = Boolean.FALSE;
            items.get(i).getAllowAction().setCanEdit(policy.isCanEdit());
            
//            tmp = groupPolicy.indexOf("DELETE")>-1;
//            if(tmp==null) tmp = Boolean.FALSE;
            items.get(i).getAllowAction().setCanDelete(policy.isCanDelete());
            
//            tmp = groupPolicy.indexOf("PRINT")>-1;
//            if(tmp==null) tmp = Boolean.FALSE;
            items.get(i).getAllowAction().setCanPrint(policy.isCanPrint());
            
//            tmp = groupPolicy.indexOf("APPROVE")>-1;
//            if(tmp==null) tmp = Boolean.FALSE;
            items.get(i).getAllowAction().setCanApprove(policy.isCanApprove());
            i++;
        }
        tableModel.add(items);
    }
    
    private void validasi(){
       boolean valid;
       valid = !((NameValueList) cmbGroup.getSelectedItem()).getKey().equals("-1");
       //if (valid){valid =!((NameValueList) cmbModul.getSelectedItem()).getKey().equals("-1");}
        if (!valid) {
            JOptionPane.showMessageDialog(this, "Grup pengguna belum ditentukan.!"
            ,"Warning",JOptionPane.WARNING_MESSAGE);}
        
        if (valid) { saveData(); }
    }
    
     protected void saveData() {
         groupAccess = new ArrayList<>();
         StringBuilder allow= new StringBuilder();
        for (int i=0;i<grid.getRowCount();i++){
            allow.setLength(0);
            SystemGroupAccess grp = new SystemGroupAccess();
            int groupId=Integer.parseInt(((NameValueList) cmbGroup.getSelectedItem()).getKey());
            int menuId = Integer.parseInt(grid.getValueAt(i,8).toString());
            grp.setId(new SystemGroupAccessId(groupId, menuId));
            allow.append("");
            grp.getSystemGroup().setGroupId(groupId);
            grp.getSystemMenu().setMenuId(menuId);
            if (grid.getValueAt(i, COL_ADD)!=null) if ((Boolean)grid.getValueAt(i, COL_ADD)) allow.append(Constants.POLICY_ADD);
            if (grid.getValueAt(i, COL_EDIT)!=null) if ((Boolean)grid.getValueAt(i, COL_EDIT)) allow.append(Constants.POLICY_EDIT);
            if (grid.getValueAt(i, COL_DELETE)!=null) if ((Boolean)grid.getValueAt(i, COL_DELETE)) allow.append(Constants.POLICY_DELETE);
            if (grid.getValueAt(i, COL_PRINT)!=null) if ((Boolean)grid.getValueAt(i,COL_PRINT)) allow.append(Constants.POLICY_PRINT);
            if (grid.getValueAt(i, COL_APPROVE)!=null) if ((Boolean)grid.getValueAt(i,COL_APPROVE)) allow.append(Constants.POLICY_APPROVAL);
            grp.setPolicy(allow.toString());
            groupAccess.add(grp);
        }
        boolean saved = false;
        try{
            saved = ServicesList.getSystemGroupAccessService().save(groupAccess);
            
        } catch(Exception ex){
            log.error(ex);
            JOptionPane.showMessageDialog(this, "Data gagal disimpan."
            ,"Error",JOptionPane.ERROR_MESSAGE);
        }
        
       // initButtonState(!saved);
    }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jToolBar1 = new javax.swing.JToolBar();
        btnSave = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        grid = new javax.swing.JTable();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        cmbGroup = new javax.swing.JComboBox();
        cmbModul = new javax.swing.JComboBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jToolBar1.setFloatable(false);
        jToolBar1.setRollover(true);
        jToolBar1.setMaximumSize(new java.awt.Dimension(267, 10));
        jToolBar1.setMinimumSize(new java.awt.Dimension(267, 10));
        jToolBar1.setSize(this.getWidth(), 50);

        btnSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/filesave.png"))); // NOI18N
        btnSave.setText("Save");
        btnSave.setFocusable(false);
        btnSave.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        btnSave.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });
        jToolBar1.add(btnSave);

        jButton5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/reload.png"))); // NOI18N
        jButton5.setText("Load");
        jButton5.setFocusable(false);
        jButton5.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        jButton5.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButton5.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton5ActionPerformed(evt);
            }
        });
        jToolBar1.add(jButton5);

        grid.setRowSelectionAllowed(false);
        jScrollPane1.setViewportView(grid);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE)
        );

        jLabel1.setText("Kelompok Pengguna :");

        jLabel2.setText("Modul :");

        cmbGroup.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        cmbModul.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(30, 30, 30)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cmbGroup, 0, 187, Short.MAX_VALUE)
                    .addComponent(cmbModul, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(cmbGroup, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(cmbModul, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(2, 2, 2))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
            .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        // TODO add your handling code here:
      validasi();
    }//GEN-LAST:event_btnSaveActionPerformed

    private void jButton5ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton5ActionPerformed
        // TODO add your handling code here:
       loadData();
    }//GEN-LAST:event_jButton5ActionPerformed

    class GridActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
                int idx =  grid.getSelectedRow();
                //String jenis = ((NameValueList) cmbDiskonJenis.getSelectedItem()).getKey();
                //itemHpp.getItemDiskons().get(idx).setJenis(jenis);
              //  items.get(idx).getAllowAction().setCanAdd(true);
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnSave;
    private javax.swing.JComboBox cmbGroup;
    private javax.swing.JComboBox cmbModul;
    private javax.swing.JTable grid;
    private javax.swing.JButton jButton5;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JToolBar jToolBar1;
    // End of variables declaration//GEN-END:variables
}




class HeaderRenderer extends JCheckBox implements TableCellRenderer {
    private final JLabel label = new JLabel();
    private int targetColumnIndex;
    
    
    public HeaderRenderer(JTableHeader header, int index,String labelCaption) {
        super((String)null);
        label.setText(labelCaption);
        this.targetColumnIndex = index;
        setOpaque(false);
        setFont(header.getFont());
        header.addMouseListener(new MouseAdapter() {
            @Override public void mouseClicked(MouseEvent e) {
                JTableHeader header = (JTableHeader)e.getSource();
                JTable table = header.getTable();
                TableColumnModel columnModel = table.getColumnModel();
                int vci = columnModel.getColumnIndexAtX(e.getX());
                int mci = table.convertColumnIndexToModel(vci);
                if(mci == targetColumnIndex) {
                    TableColumn column = columnModel.getColumn(vci);
                    Object v = column.getHeaderValue();
                    boolean b = StatusCheckBox.DESELECTED.equals(v)?true:false;
                    TableModel m = table.getModel();
                    for(int i=0; i<m.getRowCount(); i++) m.setValueAt(b, i, mci);
                    column.setHeaderValue(b?StatusCheckBox.SELECTED:StatusCheckBox.DESELECTED);
                    //header.repaint();
                }
            }
        });
    }


    
    
    
    @Override public Component getTableCellRendererComponent(JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) {
        TableCellRenderer r = tbl.getTableHeader().getDefaultRenderer();
        JLabel l = (JLabel)r.getTableCellRendererComponent(tbl, val, isS, hasF, row, col);
        if(targetColumnIndex==tbl.convertColumnIndexToModel(col)) {
            if(val instanceof StatusCheckBox) {
                switch((StatusCheckBox)val) {
                  case SELECTED:      setSelected(true);  setEnabled(true);  break;
                  case DESELECTED:    setSelected(false); setEnabled(true);  break;
                  case INDETERMINATE: setSelected(true);  setEnabled(false); break;
                }
            }else{
                setSelected(true); setEnabled(false);
            }
            label.setIcon(new ComponentIcon(this));
            l.setIcon(new ComponentIcon(label));
            l.setText(null); //XXX: Nimbus???
        //    l.setHorizontalAlignment(SwingConstants.CENTER);
        //}else{
        //    l.setHorizontalAlignment(SwingConstants.LEFT);
        }

//         System.out.println("getHeaderRect: " + tbl.getTableHeader().getHeaderRect(col));
//         System.out.println("getPreferredSize: " + l.getPreferredSize());
//         System.out.println("getMaximunSize: " + l.getMaximumSize());
//         System.out.println("----");
//         if(l.getPreferredSize().height>1000) { //XXX: Nimbus???
//             System.out.println(l.getPreferredSize().height);
//             Rectangle rect = tbl.getTableHeader().getHeaderRect(col);
//             l.setPreferredSize(new Dimension(0, rect.height));
//         }
        return l;
    }
    @Override public void updateUI() {
        setText(null); //XXX: Nimbus??? Header height bug???
        super.updateUI();
    }
}

class ComponentIcon implements Icon{
    private final JComponent cmp;
    public ComponentIcon(JComponent cmp) {
        this.cmp = cmp;
    }
    @Override public int getIconWidth() {
        return cmp.getPreferredSize().width;
    }
    @Override public int getIconHeight() {
        return cmp.getPreferredSize().height;
    }
    @Override public void paintIcon(Component c, Graphics g, int x, int y) {
        SwingUtilities.paintComponent(g, cmp, (Container)c, x, y, getIconWidth(), getIconHeight());
    }
}